package 夏希尔.工具包;

public class 夏希尔括号匹配工具 extends 系统工具封装包 {

	private final static int 左 = 0;

	private final static int 右 = 1;

	private static char[][] 检查并格式化规则数组到字符二维数组(文本型[] 规则数组) {

		if (规则数组 == 空对象())

			规则数组 = 新建文本数组(0);

		char[][] 处理结果 = new char[数组取长度(规则数组)][];

		for (int 下标 = 0; 下标 < 数组取长度(处理结果); 下标++) {

			if (规则数组[下标] == 空对象())

				规则数组[下标] = 新建文本();

			处理结果[下标] = 文本转字符数组(规则数组[下标]);

		}

		return 处理结果;

	}

	private static char[][] 检查筛选与格式化规则(char[][] 规则) {

		// 在这里 [下标][左] 的位置就是左括号对应的二维存放位置 [下标][右] 是右括号

		if (规则 == 空对象() || 数组取长度(规则) <= 0) // 如果规则为空或规则长度为0
			return new char[][] { { 空字符, 空字符 } }; // 那么直接返回一个规则长度为1的规则,但是这个规则内容0的位置和1的位置为空
													// 这样的目的是为了让程序不会因为空值而报错,提高代码健壮性

		for (int 下标 = 0; 下标 < 数组取长度(规则); 下标++) { // 遍历规则

			if (规则[下标] == 空对象() || 数组取长度(规则[下标]) <= 0) // 如果下标位置的元素为空或者长度不符合一对括号(也就是长度为0),

				规则[下标] = new char[] { 空字符, 空字符 }; // 那么将两个位置重置成一样的

			else if (数组取长度(规则[下标]) <= 1) // 如果下标位置的元素长度不符合一对括号(也就是长度为1)

				规则[下标] = new char[] { 规则[下标][左], 规则[下标][左] };// 那么将两个位置重置成一样的

			else if (数组取长度(规则[下标]) >= 2) // 如果下标位置的元素长度不符合一对括号(也就是长度大于2)

				规则[下标] = new char[] { 规则[下标][左], 规则[下标][右] };// 那么只取最前面两个位置的值

		}
		return 规则;
	}

	private static boolean 切割(char[] 字符组, char[][] 规则, 封装_栈<文本型> 最终结果栈) {

		封装_栈<匹对分页> 临时栈 = 封装_栈.新建栈();

		封装_栈<匹对分页> 分页结果栈 = 封装_栈.新建栈();

		父级循环: for (int 下标 = 0; 下标 < 数组取长度(字符组); 下标++) {

			if (是否为左括号(字符组[下标], 规则)) {

				匹对分页 分页 = 匹对分页.新建匹对分页();

				分页.左括号字符 = 字符组[下标];

				分页.左括号字符_索引 = 下标;

				临时栈.入栈(分页);

				分页结果栈.入栈(分页);

			} else {

				if (取反(临时栈.容器是否为空())) {

					匹对分页 栈顶元素 = 临时栈.出栈();

					for (char[] 括号对 : 规则)

						if (括号对[右] == 字符组[下标] && 栈顶元素.左括号字符 == 括号对[左]) {

							栈顶元素.右括号字符 = 字符组[下标];

							栈顶元素.右括号字符_索引 = 下标;

							continue 父级循环;

						}

					临时栈.入栈(栈顶元素);

				}

			}

		}

		为结果栈赋值(字符组, 分页结果栈, 最终结果栈);

		return 临时栈.容器是否为空();

	}

	private static void 为结果栈赋值(char[] 字符组, 封装_栈<匹对分页> 结果分页栈容器, 封装_栈<文本型> 最终结果栈) {

		while (取反(结果分页栈容器.容器是否为空())) {

			匹对分页 分页 = 结果分页栈容器.出栈();

			int 起始位置 = 分页.左括号字符_索引 + 1;

			int 结束位置 = 分页.右括号字符_索引;

			文本累加器 累加器 = 文本累加器.新建文本累加器(); // 新建一个高效文本累加器

			for (int 下标 = 起始位置; 下标 < 结束位置; 下标++)

				累加器.添加到末尾(字符组[下标]); // 字符组[下标] 添加到累加器末尾

			最终结果栈.入栈(累加器.转文本()); // 文本累加器转成文本来使用

		}

		最终结果栈.入栈(新建文本(字符组)); // 这里将原始字符组也重新转成文本入栈

	}

	private static boolean 是否为左括号(char 字符, char[][] 规则) {

		for (char[] 规则括号对 : 规则)

			if (规则括号对[左] == 字符) // 规则括号对[左] 是左括号所在的位置 规则括号对[右] 是右括号

				return 真;

		return 假;

	}

	private char[] 字符组;

	private char[][] 括号规则;

	private boolean 是否正确;

	private boolean 是否已经检查;

	private 封装_栈<文本型> 结果容器 = 封装_栈.新建栈();

	public 夏希尔括号匹配工具(文本型 文本, 文本型... 规则文本_可变数组) {

		this.重设规则(规则文本_可变数组);

		this.重设字符组(文本);

	}

	public 夏希尔括号匹配工具(文本型 文本, char[]... 规则组_可变数组) {

		this.重设规则(规则组_可变数组);

		this.重设字符组(文本);

	}

	public 夏希尔括号匹配工具(char[] 文本字符组, char[]... 规则组_可变数组) {

		this.重设规则(规则组_可变数组);

		this.重设字符组(文本字符组);

	}

	public 夏希尔括号匹配工具(char[] 文本字符组, 文本型... 规则文本_可变数组) {

		this.重设规则(规则文本_可变数组);

		this.重设字符组(文本字符组);

	}

	public void 重设规则(文本型... 规则文本_可变数组) {

		this.重设规则(检查并格式化规则数组到字符二维数组(规则文本_可变数组));

	}

	public void 重设字符组(文本型 文本) {

		this.重设字符组(文本转字符数组(文本));

	}

	public void 重设规则(char[]... 规则组_可变数组) {

		this.括号规则 = 检查筛选与格式化规则(规则组_可变数组);

		this.是否已经检查 = 假;

		this.是否正确 = 假;

	}

	public void 重设字符组(char[] 文本字符组) {

		this.字符组 = 文本字符组;

		this.是否已经检查 = 假;

		this.是否正确 = 假;

	}

	public boolean 是否合规() {

		if (是否已经检查)

			return 是否正确;

		是否已经检查 = 真;

		return (是否正确 = 切割(字符组, 括号规则, (结果容器 = 封装_栈.新建栈())));

	}

	public 文本型[] 切割抠字() {

		文本型[] 文本数组 = 新建文本数组(结果容器.取容器内容大小());

		if (是否正确) {

			return 结果容器.转数组(文本数组);

		}

		是否正确 = 切割(字符组, 括号规则, (结果容器 = 封装_栈.新建栈()));

		是否已经检查 = 真;

		return 结果容器.转数组(文本数组);

	}
}
